import { AmbientLight, DirectionalLight, HemisphereLight, PointLight, Vector3 } from "three"

/**
 * 光线
 */
export const allLights: any[] = [];
const WHITE_COLOR = 'rgb(255, 255, 255)';
const LIGHT_POSITION: Vector3 = new Vector3(0, 50, 100);

// 添加环境光
export const ambientLight = new AmbientLight(WHITE_COLOR, 0.8);

// 点光源
export const pointLight = new PointLight(
    WHITE_COLOR,
    10,
    600,
    1
);
pointLight.position.set(LIGHT_POSITION.x, LIGHT_POSITION.y, LIGHT_POSITION.z);// 设置点光源位置

allLights.push(ambientLight, pointLight)



interface LightOptions {
    intensity: number;
    color?: string;
    distance?: number;
    decay?: number;
    position?: Vector3;
    groundColor?: string;
}

abstract class Light {
    protected readonly WHITE_COLOR = "rgb(255, 255, 255)";
    protected readonly LIGHT_POSITION = new Vector3(0, 50, 100);

    protected readonly light: any;

    constructor(options: LightOptions) {
        this.light = this.createLight(options);
    }

    public getLight(): any {
        return this.light;
    }

    protected abstract createLight(options: LightOptions): any;
}

class PointLightFactory extends Light {
    protected createLight(options: LightOptions): any {
        const pointLight = new PointLight(options.color || this.WHITE_COLOR, options.intensity, options.distance || 0, options.decay || 0);
        pointLight.position.copy(options.position || new Vector3(0, 0, 0));
        return pointLight;
    }
}

class DirectionalLightFactory extends Light {
    protected createLight(options: LightOptions): any {
        const directionalLight = new DirectionalLight(options.color || this.WHITE_COLOR, options.intensity);
        directionalLight.position.copy(options.position || new Vector3(0, 0, 0));
        return directionalLight;
    }
}

class HemisphereLightFactory extends Light {
    protected createLight(options: LightOptions): any {
        const hemisphereLight = new HemisphereLight(options.color || this.WHITE_COLOR, options.groundColor || this.WHITE_COLOR, options.intensity);
        hemisphereLight.position.copy(options.position || new Vector3(0, 0, 0));
        return hemisphereLight;
    }
}

export class LightManager {
    private readonly allLights: any[] = [];

    public createLight(lightType: string, options: LightOptions, ext: {}): void {
        let lightFactory: Light;
        switch (lightType) {
            case "point":
                lightFactory = new PointLightFactory(options);
                break;
            case "directional":
                lightFactory = new DirectionalLightFactory(options);
                break;
            case "hemisphere":
                lightFactory = new HemisphereLightFactory(options);
                break;
            default:
                throw new Error(`Invalid light type: ${lightType}`);
        }
        const light = lightFactory.getLight();
        this.allLights.push(light);
    }

    public createAmbientLight(options: LightOptions): void {
        const ambientLight = new AmbientLight(options.color || "rgb(255, 255, 255)", options.intensity || 0.8);
        this.allLights.push(ambientLight);
    }

    public getLights(): any[] {
        return this.allLights;
    }
}